package com.example.zhilierp.util;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

/**
 * 日期时间工具类
 * 提供日期时间的格式化、解析、计算等功能
 */
public class DateUtils {

    /**
     * 默认日期时间格式
     */
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    
    /**
     * 日期格式
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
    
    /**
     * 时间格式
     */
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
    
    /**
     * 年月格式
     */
    public static final String DEFAULT_YEAR_MONTH_FORMAT = "yyyy-MM";

    /**
     * Date转LocalDateTime
     * @param date Date对象
     * @return LocalDateTime对象
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        if (date == null) {
            return null;
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    }

    /**
     * LocalDateTime转Date
     * @param localDateTime LocalDateTime对象
     * @return Date对象
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return null;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zoneId).toInstant();
        return Date.from(instant);
    }

    /**
     * Date转LocalDate
     * @param date Date对象
     * @return LocalDate对象
     */
    public static LocalDate dateToLocalDate(Date date) {
        if (date == null) {
            return null;
        }
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDate();
    }

    /**
     * LocalDate转Date
     * @param localDate LocalDate对象
     * @return Date对象
     */
    public static Date localDateToDate(LocalDate localDate) {
        if (localDate == null) {
            return null;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay(zoneId).toInstant();
        return Date.from(instant);
    }

    /**
     * 格式化LocalDateTime
     * @param localDateTime LocalDateTime对象
     * @param pattern 格式模式
     * @return 格式化后的字符串
     */
    public static String formatLocalDateTime(LocalDateTime localDateTime, String pattern) {
        if (localDateTime == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return localDateTime.format(formatter);
    }

    /**
     * 格式化LocalDateTime（默认格式）
     * @param localDateTime LocalDateTime对象
     * @return 格式化后的字符串
     */
    public static String formatLocalDateTime(LocalDateTime localDateTime) {
        return formatLocalDateTime(localDateTime, DEFAULT_DATETIME_FORMAT);
    }

    /**
     * 格式化LocalDate
     * @param localDate LocalDate对象
     * @param pattern 格式模式
     * @return 格式化后的字符串
     */
    public static String formatLocalDate(LocalDate localDate, String pattern) {
        if (localDate == null) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return localDate.format(formatter);
    }

    /**
     * 格式化LocalDate（默认格式）
     * @param localDate LocalDate对象
     * @return 格式化后的字符串
     */
    public static String formatLocalDate(LocalDate localDate) {
        return formatLocalDate(localDate, DEFAULT_DATE_FORMAT);
    }

    /**
     * 解析字符串为LocalDateTime
     * @param dateStr 日期时间字符串
     * @param pattern 格式模式
     * @return LocalDateTime对象
     */
    public static LocalDateTime parseLocalDateTime(String dateStr, String pattern) {
        if (dateStr == null || dateStr.isEmpty()) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDateTime.parse(dateStr, formatter);
    }

    /**
     * 解析字符串为LocalDateTime（默认格式）
     * @param dateStr 日期时间字符串
     * @return LocalDateTime对象
     */
    public static LocalDateTime parseLocalDateTime(String dateStr) {
        return parseLocalDateTime(dateStr, DEFAULT_DATETIME_FORMAT);
    }

    /**
     * 解析字符串为LocalDate
     * @param dateStr 日期字符串
     * @param pattern 格式模式
     * @return LocalDate对象
     */
    public static LocalDate parseLocalDate(String dateStr, String pattern) {
        if (dateStr == null || dateStr.isEmpty()) {
            return null;
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return LocalDate.parse(dateStr, formatter);
    }

    /**
     * 解析字符串为LocalDate（默认格式）
     * @param dateStr 日期字符串
     * @return LocalDate对象
     */
    public static LocalDate parseLocalDate(String dateStr) {
        return parseLocalDate(dateStr, DEFAULT_DATE_FORMAT);
    }

    /**
     * 获取当前日期时间
     * @return 当前LocalDateTime
     */
    public static LocalDateTime getCurrentLocalDateTime() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前日期
     * @return 当前LocalDate
     */
    public static LocalDate getCurrentLocalDate() {
        return LocalDate.now();
    }

    /**
     * 计算两个日期之间的天数差
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 天数差
     */
    public static long getDaysBetween(LocalDate startDate, LocalDate endDate) {
        if (startDate == null || endDate == null) {
            return 0;
        }
        return ChronoUnit.DAYS.between(startDate, endDate);
    }

    /**
     * 计算两个日期时间之间的小时差
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 小时差
     */
    public static long getHoursBetween(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0;
        }
        return ChronoUnit.HOURS.between(startTime, endTime);
    }

    /**
     * 计算两个日期时间之间的分钟差
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 分钟差
     */
    public static long getMinutesBetween(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0;
        }
        return ChronoUnit.MINUTES.between(startTime, endTime);
    }

    /**
     * 计算两个日期时间之间的秒差
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 秒差
     */
    public static long getSecondsBetween(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0;
        }
        return ChronoUnit.SECONDS.between(startTime, endTime);
    }

    /**
     * 在日期上增加指定天数
     * @param date 日期
     * @param days 要增加的天数
     * @return 增加后的日期
     */
    public static LocalDate plusDays(LocalDate date, long days) {
        if (date == null) {
            return null;
        }
        return date.plusDays(days);
    }

    /**
     * 在日期上减少指定天数
     * @param date 日期
     * @param days 要减少的天数
     * @return 减少后的日期
     */
    public static LocalDate minusDays(LocalDate date, long days) {
        if (date == null) {
            return null;
        }
        return date.minusDays(days);
    }

    /**
     * 在日期时间上增加指定小时
     * @param dateTime 日期时间
     * @param hours 要增加的小时数
     * @return 增加后的日期时间
     */
    public static LocalDateTime plusHours(LocalDateTime dateTime, long hours) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.plusHours(hours);
    }

    /**
     * 在日期时间上减少指定小时
     * @param dateTime 日期时间
     * @param hours 要减少的小时数
     * @return 减少后的日期时间
     */
    public static LocalDateTime minusHours(LocalDateTime dateTime, long hours) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.minusHours(hours);
    }

    /**
     * 判断日期是否在指定范围内
     * @param date 要判断的日期
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 是否在范围内
     */
    public static boolean isBetween(LocalDate date, LocalDate startDate, LocalDate endDate) {
        if (date == null || startDate == null || endDate == null) {
            return false;
        }
        return date.isAfter(startDate.minusDays(1)) && date.isBefore(endDate.plusDays(1));
    }

    /**
     * 判断日期时间是否在指定范围内
     * @param dateTime 要判断的日期时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 是否在范围内
     */
    public static boolean isBetween(LocalDateTime dateTime, LocalDateTime startTime, LocalDateTime endTime) {
        if (dateTime == null || startTime == null || endTime == null) {
            return false;
        }
        return dateTime.isAfter(startTime.minusNanos(1)) && dateTime.isBefore(endTime.plusNanos(1));
    }
}